﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Communication.Net.Telnet.KeyCommands;

namespace UtilZ.Dotnet.Ex.Communication.Net.Ftp
{
    internal class FtpCommandManager
    {
        private static readonly Dictionary<string, IFtpCommand> _ftpCommandDic = null;

        static FtpCommandManager()
        {
            var dic = new Dictionary<string, IFtpCommand>();

            AddFtpCommand(dic, new FtpABORCommand());
            AddFtpCommand(dic, new FtpAPPECommand());
            AddFtpCommand(dic, new FtpAUTHCommand());
            AddFtpCommand(dic, new FtpCCCCommand());
            AddFtpCommand(dic, new FtpCDUPCommand());
            AddFtpCommand(dic, new FtpCWDCommand());
            AddFtpCommand(dic, new FtpDELECommand());
            AddFtpCommand(dic, new FtpFEATCommand());
            AddFtpCommand(dic, new FtpLISTCommand());
            AddFtpCommand(dic, new FtpMDTMCommand());
            AddFtpCommand(dic, new FtpMFMTCommand());
            AddFtpCommand(dic, new FtpMKDCommand());
            AddFtpCommand(dic, new FtpNLSTCommand());
            AddFtpCommand(dic, new FtpNOOPCommand());
            AddFtpCommand(dic, new FtpOPTSCommand());
            AddFtpCommand(dic, new FtpPASSCommand());
            AddFtpCommand(dic, new FtpPASVCommand());
            AddFtpCommand(dic, new FtpPORTCommand());
            AddFtpCommand(dic, new FtpPWDCommand());
            AddFtpCommand(dic, new FtpQUITCommand());
            AddFtpCommand(dic, new FtpREINCommand());
            AddFtpCommand(dic, new FtpRESTCommand());
            AddFtpCommand(dic, new FtpRETRCommand());
            AddFtpCommand(dic, new FtpRMDCommand());
            AddFtpCommand(dic, new FtpRNFRCommand());
            AddFtpCommand(dic, new FtpRNTOCommand());
            AddFtpCommand(dic, new FtpSITECommand());
            AddFtpCommand(dic, new FtpSIZECommand());
            AddFtpCommand(dic, new FtpSTATCommand());
            AddFtpCommand(dic, new FtpSTORCommand());
            AddFtpCommand(dic, new FtpSYSTCommand());
            AddFtpCommand(dic, new FtpTYPECommand());
            AddFtpCommand(dic, new FtpUSERCommand());

            _ftpCommandDic = dic;
        }

        private static void AddFtpCommand(Dictionary<string, IFtpCommand> dic, IFtpCommand command)
        {
            var names = command.Names;
            if (names == null || names.Length == 0)
            {
                throw new ArgumentNullException($"ftp命令类型\"{command.ToString()}\"名称为空或null");
            }

            IFtpCommand oldCommand;
            foreach (var name in names)
            {
                if (dic.TryGetValue(name, out oldCommand))
                {
                    throw new ArgumentException($"ftp\"类型\"{command.ToString()}\"与类型\"{oldCommand.ToString()}\"具有相同的命令名称\"{name}");
                }

                dic.Add(name, command);
            }
        }

        public static bool TryGetFtpCommand(string name, out IFtpCommand command)
        {
            return _ftpCommandDic.TryGetValue(name, out command);
        }

        public static IEnumerable<string> GetCommands()
        {
            return _ftpCommandDic.Keys;
        }
    }
}
